package com.isoftstone.securityframework.device.auth.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import org.apache.shiro.web.util.WebUtils;

import com.isoftstone.securityframework.api.crypt.CryptUtil;
import com.isoftstone.securityframework.api.crypt.DESDecrypt;
import com.isoftstone.securityframework.api.crypt.DESEncrypt;
import com.isoftstone.securityframework.api.crypt.MD5Encrypt;
import com.isoftstone.securityframework.device.Device;

/**
 * 设备Filter
 * 根据和老翟的自定义协议，终端第一次访问不带设备id，服务端返回401同时返回加密因子
 * 终端接收到401后，根据加密因子对设备id进行加密，发起第二次访问
 * 服务端根据cookie查找加密因子对设备id进行解密，认证。
 * 
 * @author david
 */
public class DeviceFilter extends UserFilter {

	/**
	 * 如果携带了id，则允许访问。如果过没有id。返回false
	 */
	@Override
	protected boolean isAccessAllowed(ServletRequest request,
			ServletResponse response, Object mappedValue) {
		String authenticate = WebUtils.toHttp(request).getHeader("Authorization");
		try {
			if (authenticate != null && !"".equals(authenticate)) {
				DESDecrypt des = new DESDecrypt();
				Cookie[] cookies = WebUtils.toHttp(request).getCookies();
				for (Cookie cookie : cookies) {
					if (cookie.getName().equalsIgnoreCase("jsessionid")) {
						//根据cookie获取session,进而获取加密因子对设备id解密
						Session session = SecurityUtils.getSecurityManager().getSession(new WebSessionKey(cookie.getValue(),request,response));

						byte[] t = CryptUtil.decode(authenticate);
						String key = session.getAttribute("key").toString();
						String deviceId = new String(des.decrypt(t, key),"utf-8");
						Device device = new com.isoftstone.securityframework.device.domain.Device(deviceId);
						device.login();
						return true;
					}
				}
				return false;
			}
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 当设备没有携带id访问被保护资源时返回401
	 */
	@Override
	protected boolean onAccessDenied(ServletRequest request,
			ServletResponse response) throws Exception {
		saveRequest(request);
		// 将加密因子存放在session中
		DESEncrypt des = new DESEncrypt();
		String key = des.initKey();
		Session session = this.getSubject(request, response).getSession(true);
		//返回cookie
		WebUtils.toHttp(response).setHeader("Set-Cookie", "JSESSIONID=" + session.getId());
		session.setAttribute("key", key);

		// 返回加密因子
		WebUtils.toHttp(response).setHeader("www-Authenticate", key);
		WebUtils.toHttp(response)
				.sendError(HttpServletResponse.SC_UNAUTHORIZED);
		return false;
	}
	
	public static void main(String[] args) {
		MD5Encrypt d = new MD5Encrypt();
		try {
			String code ="admin";
			byte[] b = d.encrypt(code.getBytes(), null);
			String s = CryptUtil.encodeBytes(b);
			
			System.out.println(s);
			System.out.println(s.getBytes());
			
//			System.out.println(new java.math.BigInteger(d.encrypt(code.getBytes(), null)).toString(16));
//
//			System.out.println(d.encrypt(CryptUtil.decryptBASE64(code), null));
//			System.out.println(new java.math.BigInteger(d.encrypt(CryptUtil.decryptBASE64(code), null)).toString(16));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
